package com.springcloud.controller;

import bcs.util.time.BcsTimeUtil;
import com.springcloud.aop.OperationLogger;
import com.springcloud.dto.Response;
import com.springcloud.dto.TaskDto;
import com.springcloud.dto.TaskWMSDto;
import com.springcloud.dto.WebResultDto;

import com.springcloud.enums.OperateType;
import com.springcloud.model.DestinationModel;
import com.springcloud.model.TaskModel;
import com.springcloud.service.TaskExeService;
import com.springcloud.utils.ConstantUtil;
import com.springcloud.utils.HttpClientHelper;
import lombok.extern.slf4j.Slf4j;
import okhttp3.Call;
import okhttp3.Callback;
import org.jetbrains.annotations.NotNull;
import org.springframework.scheduling.annotation.Async;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
@RestController
public class TaskExeController {
    @Resource
    TaskExeService taskExeService;
    /**
     * 插入本地任务
     */
    @OperationLogger(modelName = "插入本地任务", option = "/rest/insertSingleTask")
    @PostMapping("/rest/insertSingleTask")
    public Response<String> insertSingleTask(@RequestBody TaskDto dto) {
        Response<String> result = new Response<>();
        if (dto == null) return result;
        TaskModel model = changeTask(dto);
        result = estimateTask(model);
        if (!result.getMessage().equals("fail")) return result;
        if (taskExeService.save(model)) result.success("任务添加成功");
        return result;
    }

    /**
     * 插入远程任务
     */
    @OperationLogger(modelName = "插入wms任务", option = "/rest/insertWMSTask")
    @PostMapping("/rest/insertWMSTask")
    public Response<String> insertWMSTask(@RequestBody TaskWMSDto dto) {
        Response<String> result = new Response<>();
        if (dto == null) return result;
        TaskModel task = changeWMSTask(dto);
        result = estimateTask(task);
        if (!result.getMessage().equals("fail")) return result;
        if (!taskExeService.save(task)) {
            result.fali("插入数据库失败");
            return result;
        }
        execute(task,result);
        result.success();
        return result;
    }

    /**
     * 执行任务
     */
    @OperationLogger(modelName = "执行任务", option = "/rest/executeTask")
    @PostMapping("/rest/executeTask")
    public Response<String> executeTask(@RequestBody TaskDto tasknoDto) {
        Response<String> result = new Response<>();
        if (tasknoDto == null ) return result;
        TaskModel task= taskExeService.getOneTask(tasknoDto.getTaskNo());
        execute(task,result);
        return result;
    }
    @Async()
    public void execute(TaskModel task,Response<String > dto) {

        DestinationModel modelFrom = new DestinationModel("11");
        DestinationModel modelTo = new DestinationModel("12");
        DestinationModel modelTemp=new DestinationModel("13");
        List<DestinationModel> listRes = new ArrayList<>();
        modelFrom.setLocationName(task.getBinnoFrom());
        modelTo.setLocationName(task.getBinnoTo());
        if(task.getBinnoTo().startsWith("020")){
            modelTemp.setLocationName("02000");
        }else if(task.getBinnoTo().startsWith("021")){
            modelTemp.setLocationName("02100");
        }else if(task.getBinnoTo().startsWith("022")){
            modelTemp.setLocationName("02200");
        }
        modelTemp.setLocationName(task.getBinnoTo()+"0");
        listRes.add(modelFrom);
        listRes.add(modelTo);
        listRes.add(modelTemp);
        boolean flag = HttpClientHelper.createOrder(task.getTaskNo(), listRes);
        if (flag) {
            task.setTaskState(ConstantUtil.TaskState.SEND);
            taskExeService.updateTask(task);
            dto.success(null);
        }
    }



    /**
     * 如果是上架任务需要把托盘位置置0
     * 完成任务
     */
    //@OperationLogger(modelName = "完成任务", option = "/rest/finishTask")
    @PostMapping("/rest/finishTask")
    public WebResultDto finishTask(@RequestBody TaskModel model) {

        WebResultDto dto = new WebResultDto();
        //openTCS或者其他的测试发出来的任务不需要处理
        if (model.getTaskNo().length()>10) return dto;

        TaskModel task =  taskExeService.getOneTask(model.getTaskNo());
        if (!"WMS".equals(task.getTaskModel())) {
            dto.success(null);
            return dto;
        }
//        switch (task.getStatus()){
//            case "success":
//
//        }

        postWMSTask(model);
        Map<String, Object> map = new HashMap<>();
        map.put(ConstantUtil.Task.TASKNO, task.getTaskNo());
        boolean flag = taskExeService.removeByMap(map);
        if (!flag) {
            dto.setInfo("删除失败");
            return dto;
        }
        dto.success(null);
        return dto;
    }

    private void postWMSTask(TaskModel model) {
        HttpClientHelper.postWMSTask(model.getTaskNo(),  new Callback() {
            @Override
            public void onFailure(@NotNull Call arg0, @NotNull IOException arg1) {
                System.out.println("操作失败");
            }

            @Override
            public void onResponse(@NotNull Call arg0, @NotNull okhttp3.Response response) {
                    System.out.println(model.getTaskNo() + "wms任务完成");
            }
        });
    }

    /**
     * 删除任务
     */
    @OperationLogger(modelName = "删除任务", option = "/rest/deleteTask")
    @PostMapping("/rest/deleteTask")
    public WebResultDto deleteTask(@RequestBody List<TaskDto> dtoRes) {
        WebResultDto result = new WebResultDto();
        if (dtoRes == null || dtoRes.size() <= 0) return result;
        for (TaskDto dto : dtoRes) {
            if (dto == null || dto.getTaskNo() == null || dto.getTaskNo().isEmpty()) {
                result.setInfo("参数不能为空");
                continue;
            }
            Map<String, Object> map = new HashMap<>();
            map.put(ConstantUtil.Task.TASKNO, dto.getTaskNo());
            List<TaskModel> listTask = taskExeService.listByMap(map);
            if (listTask == null || listTask.size() < 1) {
                result.setInfo("任务不存在");
                continue;
            }
            TaskModel task = listTask.get(0);
            if (task.getTaskState().equals(ConstantUtil.TaskState.SEND)) {
                result.setInfo("任务状态错误");
                continue;
            }
            task.setTaskState(ConstantUtil.TaskStateString.Deleted);
            boolean flag = taskExeService.removeByMap(map);
            if (!flag) {
                result.setInfo("删除失败");
                continue;
            }
            result.success(null);
        }

        return result;
    }
    private TaskModel changeTask(TaskDto dto) {
        TaskModel model = new TaskModel();
        model.setTaskNo(dto.getTaskNo());
        model.setOperateType(dto.getOperateType());
        model.setBinnoFrom(dto.getBinnoFrom());
        model.setBinnoTo(dto.getBinnoTo());
        model.setTaskLevel(dto.getTaskLevel());
        model.setPalletno(dto.getPalletno());
        model.setTaskState(ConstantUtil.TaskState.CREATED);
        model.setTaskModel("local");
        model.setTaskTime(BcsTimeUtil.getNowTimeString());
        return model;
    }
    @NotNull
    private TaskModel changeWMSTask(@NotNull TaskWMSDto dto) {
        TaskModel model = new TaskModel();
        model.setTaskNo(dto.getTaskNo());
        model.setOperateType(dto.getOperTypeName());
        model.setBinnoFrom(dto.getBinnoFromName());
        model.setBinnoTo(dto.getBinnoToName());
        model.setTaskLevel(1);
        model.setPalletno(dto.getPalletNo());
        model.setTaskState(ConstantUtil.TaskState.CREATED);
        model.setTaskModel("WMS");
        model.setTaskTime(BcsTimeUtil.getNowTimeString());
        return model;
    }
    private Response<String> estimateTask(TaskModel task) {
        Response<String> result = new Response<>();
        if (!OperateType.contain(task.getOperateType())) {
            result.setMessage("操作类型不正确");
            return result;
        }
        return result;
    }
}
